package com.weic.easycache.http.proxy;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

import com.weic.easycache.http.Http;

import android.util.Log;

class HttpProxyServer implements IHttpServer {
	public static final boolean LOG = false;
	public final String LOG_TAG = "[HttpProxyServer]";
	public String MSG;

	public static final String SERVER_IP_ADDRESS = "127.0.0.1";
	/**如果为0，将是动态端口，ServerSocket将会绑定到一个不确定的空闲端口**/
	public static final int SERVER_PORT = 0;

	private volatile ServerSocket mServer;
	private Thread mServerThread;

	private volatile boolean loop = false, stopped = true;

	public final String mServerIpAdress;
	public final int mServerPort;
	public final String mRemoteHost;
	public final int mRemotePort;
	public final String mReferer;
	public final int mTimeout;
	public final int mMaxConnetion;

	/**
	 * @param serverIpAdress	代理服务器IP地址
	 * @param serverPort		代理服务器端口
	 * @param remoteHost		默认要访问的主机地址
	 * @param remotePort		默认要访问的主机端口
	 * @param referer			默认referer地址
	 * @param maxConnetion		最大等待连接数
	 * @param timeout			超时时间(毫秒)
	 */
	public HttpProxyServer(String serverIpAdress, int serverPort,
			String remoteHost, int remotePort, String referer, int maxConnetion, int timeout) {
		mServerIpAdress = serverIpAdress==null ? SERVER_IP_ADDRESS : serverIpAdress.trim();
		mServerPort = (serverPort<0 || serverPort>0xFFFF) ? SERVER_PORT : serverPort;
		if(remoteHost!=null && remoteHost.startsWith(Http.URL_start)) {
			remoteHost = remoteHost.substring(Http.URL_start.length());
		}
		mRemoteHost = remoteHost==null ? null : remoteHost.trim();
		mRemotePort = (remotePort<0 || remotePort>0xFFFF) ? 80 : remotePort;
		mReferer = referer==null ? null : referer.trim();
		mMaxConnetion = maxConnetion<0 ? 0 : maxConnetion;
		mTimeout = timeout<0 ? 0 : timeout;
	}
	public HttpProxyServer(String serverIpAdress, int serverPort, String remoteHost, String referer) {
		this(serverIpAdress, serverPort, remoteHost, 80, referer, 3, 0);
	}
	public HttpProxyServer(String remoteHost, String referer) {
		this(SERVER_IP_ADDRESS, SERVER_PORT, remoteHost, 80, referer, 3, 0);
	}

	public HttpProxyServer() {
		this(SERVER_IP_ADDRESS, SERVER_PORT, null, 80, null, 3, 0);
	}

	/**这里获取的将是本服务器绑定到的准确的地址，否则为null。注意：这可能是一个耗时的操作**/
	public String getProxyHostAdress() {
		return getServerMsg(SEV_ADES);
	}
	public String getProxyHost() {
		return getServerMsg(SEV_HOST);
	}
	public int getProxyPort() {
		String msg = getServerMsg(SEV_PORT);
		if(msg==null) return -1;
		return Integer.valueOf(msg);
	}

	static final int SEV_ADES	= 0;
	static final int SEV_HOST	= 1;
	static final int SEV_PORT	= 2;

	private String getServerMsg(int type) {
		String msg = null;
		if(!stopped) {	//正在启动，则等待启动完成并获取正确的地址。只有在启动之后才会变为false，否则必为true
			a: while(true) {
				if(mServer!=null) {
					while(true) {
						if(mServer.isBound()) {
							msg = getMsg(type);
							break a;
						}
					}
				}
			}
		}else {
			if(mServer!=null && mServer.isBound()) {
				msg = getMsg(type);
			}
		}
		return msg;
	}

	private String getMsg(int type) {
		String msg = null;
		switch(type) {
		case SEV_ADES:
			msg = mServer.getLocalSocketAddress().toString();
			break;
		case SEV_HOST:
			msg = mServer.getInetAddress().toString();
			break;
		case SEV_PORT:
			msg = mServer.getLocalPort()+"";
			break;
		}
		/*if(msg.startsWith("/127")) {
			msg = msg.substring(1);
		}else if(msg.startsWith("localhost/127")) {
			msg = msg.substring(10);
		}*/
		int index = msg.indexOf("127.");
		if(index > 0) {
			msg = msg.substring(index);
		}
		return msg;
	}
	
	/**启动服务
	 * @param daemon 表示是否设置为守护线程，如果是普通的java程序不能设置为守护线程，否则当主线程退出时，本服务器也会退出，
	 * 对于有UI的程序则可设为守护线程。
	 **/
	public synchronized void start(boolean daemon) {
		if(stopped) {
			mServerThread = new Thread() {
				public void run() {
					try {
						Log.d(LOG_TAG, LOG_TAG+"start------");
						//第二个参数 backlog 表示队列最大连接数，超过这个数量则连接被拒绝，默认为50
						mServer = new ServerSocket(mServerPort, mMaxConnetion, InetAddress.getByName(mServerIpAdress));
						//Log.d(LOG_TAG, mServer.getInetAddress());	///127.0.0.1
						///127.0.0.1:xxxx或者localhost/127.0.0.1:xxxx
						Log.d(LOG_TAG, LOG_TAG+"ProxyAddress:"+mServer.getLocalSocketAddress());
						loop = true;
						while(loop) {	//通过loop来中止的作用不大，如果没有请求，则由于accept()的堵塞导致不会中止
							handleClientConnect(mServer.accept());	//mServer.close()会导致这里异常而中止
						}
					}catch (IOException e) {
					}finally {
						stopped = true;
						Log.d(LOG_TAG, LOG_TAG+"stopped------");
					}
				}
			};
			//不能设置为守护线程，否则当主线程退出时，便会退出，对于有UI的程序则可设为守护线程。
			mServerThread.setDaemon(daemon);
			mServerThread.start();
			stopped = false;
		}
	}

	public synchronized void stop() {
		loop = false;
		try {
			/**
			 * 以下这句会导致mServer.accept()抛出异常而中止
			 */
			if(mServer!=null) mServer.close();
		}catch (IOException e) {
		}
	}

	public synchronized boolean isAlive() {
		return !stopped;
	}

	private void handleClientConnect(Socket socket) {
		new HttpRequestHandler(socket, mRemoteHost, mRemotePort, mReferer, mTimeout).start();
	}
}
